'use client';

import { useContext, useEffect, useRef, useState } from 'react';
import type {
  IAssignPermissionBody,
  IPagination,
  IQueryParams,
  IRole,
  IUnAssignPermissionBody,
} from '@/interfaces';
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
import {
  assignPermission,
  queryAllRole,
  queryPermissionRolesById,
  unAssignPermission,
} from '@/services/api';
import useToast from '@/hooks/useToast';
import type { TBody } from '@/types';
import Alert from '@/app/[locale]/alert/alert';
import { PermissionAdminContext } from '@/contexts/admin/auth/permission';
import AlertLoad from '@/app/[locale]/alert/load';
import { type QueryKey } from '@tanstack/query-core';

export default function UpdateRolePermissionAdminPage(this: any) {
  const context = useContext(PermissionAdminContext);
  const updateModalRef = useRef<HTMLDivElement>(null);
  const [type, setType] = useState({
    role: true,
  });

  useEffect(() => {
    onClickOpenModal();
  }, []);

  function onClickMenu(item: 'role') {
    const newType = {
      role: false,
    };

    newType[item] = true;
    setType(newType);
  }

  function onClickOpenModal() {
    getUpdateModal().show();
  }

  function onClickCloseModal() {
    if (typeof context.setUpdateRoleItem === 'function') {
      context.setUpdateRoleItem(undefined);
    }
    getUpdateModal().hide();
  }

  function getUpdateModal() {
    const current = updateModalRef.current;
    if (!current) {
      throw '更新元素不存在';
    }

    return window.bootstrap.Modal.getOrCreateInstance(current);
  }

  return (
    <div ref={updateModalRef} className="modal fade" data-bs-backdrop="static">
      <div className="modal-dialog modal-xl modal-dialog-scrollable">
        <div className="modal-content">
          <div className="modal-header">
            <h5 className="modal-title">
              {context.updateItem
                ? `${context.updateItem.name} (${context.updateItem.id})`
                : '更新权限角色'}
            </h5>
            <button
              onClick={onClickCloseModal}
              type="button"
              className="btn-close"
              aria-label="Close"
            ></button>
          </div>
          <div className="modal-body">
            <div className="row">
              <div className="col-auto">
                <div className="list-group list-group-flush">
                  <button
                    onClick={onClickMenu.bind(this, 'role')}
                    type="button"
                    className="list-group-item list-group-item-action"
                    aria-current="true"
                  >
                    角色
                  </button>
                </div>
              </div>
              <div className="col">{type.role && <RoleList />}</div>
            </div>
          </div>
        </div>
      </div>
    </div>
  );
}

const RoleList = () => {
  const context = useContext(PermissionAdminContext);
  const { show } = useToast();
  const [currentItem, setCurrentItem] = useState<IRole>();
  const queryClient = useQueryClient();
  const [params, setParams] = useState<IQueryParams>({
    page: 0,
  });
  const queryKey = [
    '/permissions',
    context.updateRoleItem?.id,
    '/roles',
    params,
  ];

  const queryPermissionRolesByIdQuery = useQuery(
    queryKey,
    async (context) => {
      return (await queryPermissionRolesById({
        id: context.queryKey[1] + '',
        query: context.queryKey[3] as any,
      })) as IPagination<IRole>;
    },
    {
      keepPreviousData: true,
    },
  );

  const unAssignPermissionMutation = useMutation(
    async (variables: TBody<IUnAssignPermissionBody>) => {
      await unAssignPermission(variables);
      await queryClient.invalidateQueries(queryKey);
    },
  );

  async function onClickRemove(item: IRole) {
    try {
      setCurrentItem(item);

      await unAssignPermissionMutation.mutateAsync({
        id: context.updateRoleItem?.id,
        data: {
          roleId: item.id + '',
        },
      });

      show({
        type: 'SUCCESS',
        message: '删除完成',
      });
    } catch (e) {
      unAssignPermissionMutation.reset();
      show({
        type: 'DANGER',
        message: e,
      });
    }
  }

  function onClickPrevious() {
    const data = queryPermissionRolesByIdQuery.data;
    if (!data) {
      show({
        type: 'DANGER',
        message: '数据不存在',
      });
      return;
    }

    const page = Math.max(0, data.pageable.page - 1);
    setParams({ ...params, page });
  }

  function onClickNext() {
    const data = queryPermissionRolesByIdQuery.data;
    if (!data) {
      show({
        type: 'DANGER',
        message: '数据不存在',
      });
      return;
    }

    const page = Math.min(data.pageable.pages, data.pageable.page + 1);
    setParams({ ...params, page });
  }

  if (queryPermissionRolesByIdQuery.data) {
    const data = queryPermissionRolesByIdQuery.data;

    return (
      <div className="row">
        <div className="col">
          <div className="vstack gap-4">
            <div className="row">
              <div className="col">
                <div className="table-responsive">
                  <table className="table table-hover align-middle">
                    <thead>
                      <tr className="text-nowrap">
                        <th scope="col" className="w-10 fw-normal">
                          ID
                        </th>
                        <th scope="col" className="w-10 fw-normal">
                          名称
                        </th>
                        <th scope="col" className="w-10"></th>
                      </tr>
                    </thead>
                    <tbody>
                      {data.content.map((item) => {
                        return (
                          <tr key={item.id} className="text-nowrap">
                            <td>{item.id}</td>
                            <td>{item.name}</td>
                            <td>
                              <button
                                disabled={
                                  item.id === currentItem?.id &&
                                  unAssignPermissionMutation.isLoading
                                }
                                onClick={onClickRemove.bind(this, item)}
                                className="btn btn-sm btn-danger"
                                type="button"
                              >
                                {item.id === currentItem?.id &&
                                unAssignPermissionMutation.isLoading ? (
                                  <span
                                    className="spinner-border spinner-border-sm me-2"
                                    role="status"
                                    aria-hidden="true"
                                  ></span>
                                ) : (
                                  <i className="bi bi-trash me-2"></i>
                                )}
                                删除
                              </button>
                            </td>
                          </tr>
                        );
                      })}
                    </tbody>
                  </table>

                  {data.content.length === 0 && (
                    <div className="text-muted">暂无角色</div>
                  )}

                  <div className="my-4">
                    <nav aria-label="角色分页">
                      <ul className="pagination justify-content-end">
                        <li className="page-item">
                          <a
                            onClick={onClickPrevious}
                            className="page-link cursor-pointer"
                          >
                            上一页
                          </a>
                        </li>
                        <li className="page-item">
                          <a
                            onClick={onClickNext}
                            className="page-link cursor-pointer"
                          >
                            下一页
                          </a>
                        </li>
                      </ul>
                    </nav>
                  </div>
                </div>
              </div>
            </div>

            <RoleAddList queryKey={queryKey} />
          </div>
        </div>
      </div>
    );
  }

  if (queryPermissionRolesByIdQuery.error) {
    return <Alert message={queryPermissionRolesByIdQuery.error} type="error" />;
  }

  return <AlertLoad />;
};

const RoleAddList = ({ queryKey }: { queryKey: QueryKey }) => {
  const { show } = useToast();
  const [params, setParams] = useState<IQueryParams>({
    page: 0,
    size: 5,
  });
  const [currentItem, setCurrentItem] = useState<IRole>();
  const context = useContext(PermissionAdminContext);
  const queryClient = useQueryClient();

  const queryAllRoleQuery = useQuery(
    ['/roles', params],
    async (context) => {
      return (await queryAllRole({
        query: context.queryKey[1] as any,
      })) as IPagination<IRole>;
    },
    {
      keepPreviousData: true,
    },
  );

  const assignPermissionMutation = useMutation(
    async (variables: TBody<IAssignPermissionBody>) => {
      await assignPermission(variables);
    },
  );

  async function onClickAdd(item: IRole) {
    try {
      setCurrentItem(item);

      await assignPermissionMutation.mutateAsync({
        id: context.updateRoleItem?.id,
        data: {
          roleId: item.id + '',
        },
      });

      await queryClient.refetchQueries(queryKey, {}, { throwOnError: true });
      show({
        type: 'SUCCESS',
        message: '添加完成',
      });
    } catch (e) {
      assignPermissionMutation.reset();
      show({
        type: 'DANGER',
        message: e,
      });
    }
  }

  function onClickPrevious() {
    const data = queryAllRoleQuery.data;
    if (!data) {
      show({
        type: 'DANGER',
        message: '数据不存在',
      });
      return;
    }

    const page = Math.max(0, data.pageable.page - 1);
    setParams({ ...params, page });
  }

  function onClickNext() {
    const data = queryAllRoleQuery.data;
    if (!data) {
      show({
        type: 'DANGER',
        message: '数据不存在',
      });
      return;
    }

    const page = Math.min(data.pageable.pages, data.pageable.page + 1);
    setParams({ ...params, page });
  }

  if (queryAllRoleQuery.data) {
    const data = queryAllRoleQuery.data;

    return (
      <div className="row">
        <div className="col">
          <div className="table-responsive">
            <table className="table table-hover align-middle">
              <thead>
                <tr className="text-nowrap">
                  <th scope="col" className="w-10 fw-normal">
                    ID
                  </th>
                  <th scope="col" className="w-10 fw-normal">
                    名称
                  </th>
                  <th scope="col" className="w-10"></th>
                </tr>
              </thead>
              <tbody>
                {data.content.map((item) => {
                  return (
                    <tr key={item.id} className="text-nowrap">
                      <td>{item.id}</td>
                      <td>{item.name}</td>
                      <td>
                        <button
                          disabled={
                            item.id === currentItem?.id &&
                            assignPermissionMutation.isLoading
                          }
                          onClick={onClickAdd.bind(this, item)}
                          className="btn btn-sm btn-light"
                          type="button"
                        >
                          {item.id === currentItem?.id &&
                          assignPermissionMutation.isLoading ? (
                            <span
                              className="spinner-border spinner-border-sm me-2"
                              role="status"
                              aria-hidden="true"
                            ></span>
                          ) : (
                            <i className="bi bi-plus-lg me-2"></i>
                          )}
                          添加
                        </button>
                      </td>
                    </tr>
                  );
                })}
              </tbody>
            </table>

            {data.content.length === 0 && (
              <div className="text-muted">暂无角色</div>
            )}

            <div className="my-4">
              <nav aria-label="角色分页">
                <ul className="pagination justify-content-end">
                  <li className="page-item">
                    <a
                      onClick={onClickPrevious}
                      className="page-link cursor-pointer"
                    >
                      上一页
                    </a>
                  </li>
                  <li className="page-item">
                    <a
                      onClick={onClickNext}
                      className="page-link cursor-pointer"
                    >
                      下一页
                    </a>
                  </li>
                </ul>
              </nav>
            </div>
          </div>
        </div>
      </div>
    );
  }

  if (queryAllRoleQuery.error) {
    return <Alert message={queryAllRoleQuery.error} type="error" />;
  }

  return <AlertLoad />;
};
